﻿#include "iic.h"
#include "utils/String/hexbin.h"
#include <QString>
#include <QDebug>

IIC::IIC(const IIC_STATUS &status, const QByteArray &data)
    : Tlv(TlvTag::Tlv_IIC_feedback, iicRes2bytes(0x00, status, data))
    , m_status(status)
    , m_data(data)
{

}

IIC::IIC(uint8_t addr, const QByteArray &data, uint16_t readLen)
    : Tlv(TlvTag::Tlv_IIC_IIC_CALL, iicReq2bytes(0x00, addr, data, readLen))
    , m_status(IIC_STATUS::IIC_STATUS_NULL)
    , m_data(data)
{
    // qDebug() << HexBin::hexFormat(value());
}

uint8_t IIC::busID() const
{
    return value().at(0);
}

uint8_t IIC::slave() const
{
    if (isIicCall()) return value().at(1);
    else return 0x00;
}

uint16_t IIC::readLen() const
{
    if (isIicCall()) return getUi16FromBytesBE(value(), 2);
    else return 0x0000;
}

IIC_STATUS IIC::status() const
{
    return m_status;
}

QByteArray IIC::data() const
{
    return m_data;
}

QString IIC::toLog() const
{
    if (isIicCall()) {
        QString rw;
        if (readLen() == 0) {
            rw = QString("Write  : %1").arg(m_data.length());
        } else {
            rw = QString("Read   : %1").arg(readLen());
        }
        QString log = QString(R"(-----------IIC_Req-----------
BusID  : %1
Slave  : 0x%2
Event  : Request
%3
Data   :
%4
)").arg(busID()).arg(QString::number(slave(), 16).toUpper(), rw, HexBin::hexFormat(m_data));
        return log;
    } else if (isIicFeedback()) {
        QString log = QString(R"(-----------IIC_Rep-----------
BusID  : %1
Event  : Response
Status : %2
Payload: %3
Data   :
%4
)").arg(busID()).arg(statusStr(m_status)).arg(m_data.length()).arg(HexBin::hexFormat(m_data));
        return log;
    }
    return Tlv::toLog();
}

bool IIC::isNull() const
{
    return m_status == IIC_STATUS::IIC_STATUS_NULL;
}

IIC IIC::fromTlv(const Tlv &tlv)
{
    if (tlv.isIicFeedback()) {
        QByteArray val = tlv.value();
        IIC_STATUS status = static_cast<IIC_STATUS>(val.at(1));
        QByteArray data = val.mid(4);
        return IIC(status, data);
    } else if (tlv.isIicCall()) {
        QByteArray val = tlv.value();
        uint8_t addr = val.at(1);
        uint16_t readLen = getUi16FromBytesBE(val, 2);
        QByteArray data = val.mid(4);
        return IIC(addr, data, readLen);
    }
    return IIC::iicNull();
}

QString IIC::statusStr(const IIC_STATUS &status)
{
    QString str;
    switch (status) {
    case IIC_STATUS_NULL:
        str = "NULL";
        break;
    case IIC_STATUS_BUSY:
        str = "BUSY";
        break;
    case IIC_STATUS_RESTART:
        str = "RESTART";
        break;
    case IIC_STATUS_END_RECEIVE:
        str = "END_RECEIVE";
        break;
    case IIC_STATUS_END_SEND:
        str = "END_SEND";
        break;
    case IIC_STATUS_ERR_ADDRFAULT:
        str = "ERR_ADDRFAULT";
        break;
    case IIC_STATUS_ERR_MASTER_NCK:
        str = "ERR_MASTER_NCK";
        break;
    case IIC_STATUS_ERR_MASTER_READ:
        str = "ERR_MASTER_READ";
        break;
    case IIC_STATUS_ERR_MASTER_WRITE:
        str = "ERR_MASTER_WRITE";
        break;
    case IIC_STATUS_ERR_MASTER_WRITE_OVERFLOW:
        str = "ERR_MASTER_WRITE_OVERFLOW";
        break;
    case IIC_STATUS_ERR_MASTER_READ_OVERFLOW:
        str = "ERR_MASTER_READ_OVERFLOW";
        break;
    default:
        str = "UNKNOWN"; // 可以添加一个未知状态的默认值
        break;
    }
    return str;
}

IIC IIC::iicNull()
{
    return IIC(IIC_STATUS::IIC_STATUS_NULL, QByteArray());
}

QByteArray IIC::iicRes2bytes(uint8_t bus, const IIC_STATUS &status, const QByteArray &data)
{
    QByteArray ret;
    ret.append(bus);
    ret.append(static_cast<uint8_t>(status));
    uint16_t dataLen = data.length();
    ret.append(getHByte(dataLen));
    ret.append(getLByte(dataLen));
    ret.append(data);
    return ret;
}

QByteArray IIC::iicReq2bytes(uint8_t bus, uint8_t addr, const QByteArray &data, uint16_t readLen)
{
    QByteArray ret;
    ret.append(bus);
    ret.append(addr);
    ret.append(getHByte(readLen));
    ret.append(getLByte(readLen));
    ret.append(data);
    return ret;
}
